#ifndef __SHIFTR__HPP__
#define __SHIFTR__HPP__
// Shiftr
struct Shiftr {
  static std::string name() { return "SHIFTR"; }
  // constexpr only if proper definition using actual modulo and remainder
  // static int apply (int l, int h) { 
  //   return shiftr(((double)(l))/((double)(h))); 
  // }

  constexpr static int apply (int l, int h) { 
    return l >> h;
  }
};

template< class A>
constexpr Expression<BinaryExpression<Expression<A>, Expression<ConstantTerm>, Shiftr> >
SHIFTR(const Expression<A> &a, int const & b)
{
  typedef BinaryExpression <Expression<A>, Expression<ConstantTerm>, Shiftr> ExprT;
  return Expression<ExprT>(ExprT(a,Expression<ConstantTerm>(b)));
}

template <int PLACE>
constexpr Expression<BinaryExpression<Expression<VariableTerm<PLACE> >, Expression<ConstantTerm>, Shiftr> >
SHIFTR(VariableTerm<PLACE> const & b, ConstantTerm const & a) {
  typedef BinaryExpression <Expression<VariableTerm<PLACE> >, Expression<ConstantTerm>, Shiftr> ExprT;
  return Expression<ExprT>(ExprT(Expression<VariableTerm<PLACE> >(b), Expression<ConstantTerm>(a)));
}

constexpr Expression<BinaryExpression<Expression<ConstantTerm>, Expression<ConstantTerm>, Shiftr> >
SHIFTR(ConstantTerm const & b, ConstantTerm const & a) {
  typedef BinaryExpression <Expression<ConstantTerm>, Expression<ConstantTerm>, Shiftr> ExprT;
  return Expression<ExprT>(ExprT(Expression<ConstantTerm>(b), Expression<ConstantTerm>(a)));
}

#endif //__SHIFTR__HPP__
